02. Testing and Class Design
Testing and Class Design
ND079 JPND C3 L5 A02 Testing And Class Design V2
Testing Around Dependencies
How do we test UserService.fancyBusiness without relying on the behavior of SalesService.fizzBuzz?
- Create a custom
SalesServicethat does what we tell it to do. - Get the fake
SalesServiceintoUserServiceso it uses that instead of its normal behavior.
Use Interfaces to Create Fake Services
public interface SalesService {
String fizzBuzz(int i);
}
Creating an interface for Services makes it easy to create fake versions of those Services. This FakeSalesService returns whatever value was used to create it when fizzBuzz is called.
public class FakeSalesService implements SalesService {
private String returnValue;
public FakeSalesService(String returnValue) {
this.returnValue = returnValue;
}
@Override
public String fizzBuzz(int i) {
return returnValue;
}
}
Decouple Dependencies
Now that we have an interface, we should update UserService so that we can replace the SalesService it uses with the one we want.
public class UserServiceImpl implements UserService {
SalesService salesService;
public UserServiceImpl(SalesService salesService) {
this.salesService = salesService;
}
public String fancyBusiness(int n) {/* hidden */ }
// remainder omitted
}
Test!
We're finally ready to test. This unit test looks for the first requirement:
- If SalesService.fizzBuzz returns “Fizz”, “Buzz”, or “FizzBuzz”, then fancyBusiness just returns that string.
@ParameterizedTest
@ValueSource(strings={"Fizz", "Buzz", "FizzBuzz"})
public void fancyBusinessFakeFizzBuzz_getsFizzBuzzString_returnsSameString(
String returnString) {
SalesService salesService = new FakeSalesService(returnString);
UserService userService = new UserServiceImpl(salesService);
// which number we pass doesn't matter, because we're controlling
// the return value of FizzBuzz
assertEquals(returnString, userService.fancyBusiness(1));
}
This test creates a FakeSalesService that will always return the string provided from our @ValueSource. When we call userService.fancyBusiness(1), the user service will then call the fizzBuzz method on the fake sales service. We then use assertEquals to verify that the fancyBusiness returns the unmodified string for "Fizz", "Buzz", and "FizzBuzz".